#include "ShaderParamTable.h"

namespace DreamEngine
{
CShaderParamTable::CShaderParamTable(void):
m_dateSizeNum(0),
m_pDataBuffer(MATH_NULL),
m_paramIter(m_shaderParams.begin(), m_shaderParams.end())
{
	m_pDataBuffer = new m_byte[1024];
}


CShaderParamTable::~CShaderParamTable(void)
{
	Destory();
}

//m_uint8 CShaderParamTable::GetParamNum()const
//{
//	return static_cast<m_uint8>(m_shaderParams.size());
//}

CShaderParam* CShaderParamTable::GetParam(const CString& name)const
{
	ShaderParamLst::const_iterator iter;
	for (iter=m_shaderParams.begin(); iter!=m_shaderParams.end(); ++iter)
	{
		if ((*iter)->GetName()==name)
		{
			return *iter;
		}
	}
	return MATH_NULL;
}

void CShaderParamTable::SetValue(const CString& name, const void* pVaule, m_uint8 vauleSize)
{
	CShaderParam* pShaderParam = GetParam(name);
	if (pShaderParam != MATH_NULL)
	{
		void* pDate = pShaderParam->GetDataPtr();
		if (pDate != MATH_NULL) memcpy(pDate, pVaule, vauleSize);
	}
}

void CShaderParamTable::SetValue(const CString& name, bool vaule)
{
	SetValue(name, &vaule, sizeof(vaule));
}

void CShaderParamTable::SetValue(const CString& name, int vaule)
{
	SetValue(name, &vaule, sizeof(vaule));
}

void CShaderParamTable::SetValue(const CString& name, float vaule)
{
	SetValue(name, &vaule, sizeof(vaule));
}

void CShaderParamTable::SetValue(const CString& name, const CVector3& vaule)
{
	SetValue(name, &vaule, sizeof(vaule));
}

void CShaderParamTable::SetValue(const CString& name, const CMatrix16& vaule)
{
	SetValue(name, &vaule, sizeof(vaule));
}

void CShaderParamTable::SetValue(const CString& name, CTexture* pTexture)
{
	const void* pBuf = pTexture->GetTextureBuf();

	SetValue(name, (const void*)&(pBuf), sizeof(void*));
}

CShaderParam* CShaderParamTable::AddParam(const CString& name,
										  CShaderParam::ParamType type, 
										  m_uint8 elemCount, 
										  m_uint8 byteSize,
										  m_uint8 registerIdx,
										  m_uint8 stMembers, 
										  void* pVaule/*=MATH_NULL*/)
{
	CShaderParam* pShaderParam = new CShaderParam( 
		name, type, elemCount, byteSize, registerIdx, stMembers);
	
	m_shaderParams.push_back(pShaderParam);
	m_dateSizeNum += byteSize;

	m_paramIter.Set(m_shaderParams.begin(), m_shaderParams.end());

	return pShaderParam;
}

void CShaderParamTable::Destory()
{
	ShaderParamLst::iterator iter;
	for (iter=m_shaderParams.begin(); iter!=m_shaderParams.end(); ++iter)
	{
		SAFE_DELETE(*iter);
	}
	SAFE_DELETE(m_pDataBuffer);
}

Error CShaderParamTable::_BuildDataBuffer()
{
	SAFE_DELETE(m_pDataBuffer);
	m_pDataBuffer = new m_byte[m_dateSizeNum+1];

	int dateOffset = 0;
	ShaderParamLst::iterator iter;
	for (iter=m_shaderParams.begin(); iter!=m_shaderParams.end(); ++iter)
	{
		(*iter)->SetDataPtr((m_byte*)(m_pDataBuffer)+dateOffset);
		dateOffset += (*iter)->GetSize();

		if (dateOffset > m_dateSizeNum)
		{
			return ERROR_MEMORY_ADDRESS_OUT_RANGE;
		}
	}

	return ERROR_OK;
	
}

}

